package com.jinlia.show.modules.base.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jinlia.show.common.core.utils.PageUtils;
import com.jinlia.show.modules.base.constant.MemberCardBalanceChangeEnum;
import com.jinlia.show.modules.base.constant.MemberCardScoreSourceEnum;
import com.jinlia.show.modules.base.model.form.MemberCardForm;
import com.jinlia.show.modules.base.system.entity.*;
import com.jinlia.show.modules.base.system.mapper.MemberCardMapper;
import com.jinlia.show.modules.base.model.po.MemberCardPO;
import com.jinlia.show.modules.base.model.query.MemberCardQuery;
import com.jinlia.show.modules.base.wxapp.entity.User;
import com.jinlia.show.modules.base.wxapp.service.UserMapperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class MemberCardMapperService extends ServiceImpl<MemberCardMapper, MemberCard> {
    @Autowired
    MemberCardScoreChangeMapperService memberCardScoreChangeMapperService;
    @Autowired
    MemberCardBalanceChangeMapperService memberCardBalanceChangeMapperService;
    @Autowired
    MemberCardTypeMapperService memberCardTypeMapperService;
    @Autowired
    UserMapperService userMapperService;


    /**
     * 积分结算
     *
     * @param order
     * @return
     */
    @Transactional
    public Boolean addScoreChangeByPayOrder(Order order) {
        if (Objects.isNull(order.getMemberCardId())) {
            log.warn("仅会员用户才可享受积分");
            return false;
        }
        if (order.getReceivableMoney().compareTo(order.getReceivedMoney()) == 1) {
            log.warn("仅全部付款的单据才会结算会员积分!!!");
            return false;
        }
        MemberCard byIdMemberCard = this.getById(order.getMemberCardId());
        //更新会员余额
        byIdMemberCard.setAvailableScore(byIdMemberCard.getAvailableScore() == null ?
                order.getReceivedMoney().intValue() : byIdMemberCard.getAvailableScore() + order.getReceivedMoney().intValue());//可用积分
        byIdMemberCard.setTotalScore(byIdMemberCard.getTotalScore() == null ?
                order.getReceivedMoney().intValue() : byIdMemberCard.getTotalScore() + +order.getReceivedMoney().intValue());//总积分
        //会员升级逻辑
        List<MemberCardType> list = memberCardTypeMapperService.lambdaQuery()
                .orderByDesc(MemberCardType::getNeedScore)//降序
                .list();
        for (MemberCardType memberCardType : list) {
            if (byIdMemberCard.getTotalScore() >= memberCardType.getNeedScore()) {
                byIdMemberCard.setTypeId(memberCardType.getId());
                break;
            }
        }
        this.lambdaUpdate()
                .set(MemberCard::getAvailableScore, byIdMemberCard.getAvailableScore())
                .set(MemberCard::getTotalScore, byIdMemberCard.getTotalScore())//总积分
                .set(MemberCard::getAvailableScore, byIdMemberCard.getAvailableScore())//可用积分
                .set(MemberCard::getTypeId, byIdMemberCard.getTypeId())//会员类型
                .set(MemberCard::getConsumedTimes, byIdMemberCard.getConsumedTimes() == null ?
                        1 : byIdMemberCard.getConsumedTimes() + 1)//消费次数
                .eq(MemberCard::getId, byIdMemberCard.getId())
                .update();
        //新增积分变动记录
        MemberCardScoreChange memberCardScoreChange = new MemberCardScoreChange();
        memberCardScoreChange.setMemberCardId(order.getMemberCardId());
        memberCardScoreChange.setScoreChange(order.getReceivedMoney().intValue());
        memberCardScoreChange.setAvailableScore(byIdMemberCard.getAvailableScore());
        memberCardScoreChange.setSourceType(MemberCardScoreSourceEnum.XF.getValue());
        memberCardScoreChange.setSourceObjectId(order.getId());
        memberCardScoreChange.setRemark("消费获取积分");
        return memberCardScoreChangeMapperService.save(memberCardScoreChange);
    }

    public IPage<MemberCardPO> getPage(MemberCardQuery queryParams) {
        // 构建分页参数
        Page<MemberCard> page = new Page<>(queryParams.getCurrent(), queryParams.getSize());
        //构造查询参数
        LambdaQueryWrapper<MemberCard> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.like(Objects.nonNull(queryParams.getName()), MemberCard::getName, queryParams.getName());
        lambdaQueryWrapper.like(Objects.nonNull(queryParams.getMobile()), MemberCard::getMobile, queryParams.getMobile());
        Page<MemberCard> pageSysUser = this.page(page, lambdaQueryWrapper);
        Page<MemberCardPO> sysMemberCardPOPage = PageUtils.tToVO(pageSysUser, MemberCardPO.class);
        //填充用户信息
        if (!CollectionUtils.isEmpty(sysMemberCardPOPage.getRecords())) {
            Set<Long> collect = sysMemberCardPOPage.getRecords().stream().map(MemberCardPO::getId).collect(Collectors.toSet());
            List<User> list = userMapperService.lambdaQuery()
                    .in(User::getMemberCardId, collect)
                    .list();
            Map<Long, List<User>> groupingByMemberCardId =  list.stream().collect(Collectors.groupingBy(User::getMemberCardId));
            sysMemberCardPOPage.getRecords().forEach(memberCardPO -> {
                memberCardPO.setUserList(groupingByMemberCardId.get(memberCardPO.getId()));
            });
        }
        return sysMemberCardPOPage;
    }

    public MemberCard updateMemberCard(MemberCardForm memberCardUpdated) {
        MemberCard byId = this.getById(memberCardUpdated.getId());
        if (!memberCardUpdated.getBalance().equals(byId.getBalance())) {
            //修改余额
            BigDecimal updateBalance = memberCardUpdated.getBalance().subtract(byId.getBalance());//变动的余额
            //新增积分变动记录
            MemberCardBalanceChange memberCardBalanceChange = new MemberCardBalanceChange();
            //余额变化记录
            memberCardBalanceChange.setMemberCardId(memberCardUpdated.getId());
            memberCardBalanceChange.setChangeEnum(MemberCardBalanceChangeEnum.TZ.getValue());//变化类型消费
            memberCardBalanceChange.setMoneyChange(updateBalance);//变动金额
            memberCardBalanceChange.setAvailableBalance(memberCardUpdated.getBalance());//变动后金额
            memberCardBalanceChange.setRemark("管理员调整:" + memberCardUpdated.getRemark());
            memberCardBalanceChangeMapperService.save(memberCardBalanceChange);
        }
        if (!memberCardUpdated.getAvailableScore().equals(byId.getAvailableScore())) {
            //修改积分
            Integer updateAvailableScore = memberCardUpdated.getAvailableScore() - byId.getAvailableScore();
            MemberCardScoreChange memberCardScoreChange = new MemberCardScoreChange();
            memberCardScoreChange.setMemberCardId(byId.getId());
            memberCardScoreChange.setScoreChange(updateAvailableScore);
            memberCardScoreChange.setAvailableScore(memberCardUpdated.getAvailableScore());
            memberCardScoreChange.setSourceType(MemberCardScoreSourceEnum.TZ.getValue());
            memberCardScoreChange.setSourceObjectId(null);
            memberCardScoreChange.setRemark("管理员调整:" + memberCardUpdated.getRemark());
            memberCardScoreChangeMapperService.save(memberCardScoreChange);
        }
        this.updateById(memberCardUpdated);
        //其他
        return memberCardUpdated;
    }


    public List<MemberCardPO> listMember(MemberCardForm memberCardForm) {
        if (memberCardForm.getKeyWordsStr() == null) {
            throw new RuntimeException("请输入搜索关键字");
        }
        if (memberCardForm.getKeyWordsStr().matches("[0-9]*")) {
            memberCardForm.setMobile(memberCardForm.getKeyWordsStr());
        } else {
            memberCardForm.setName(memberCardForm.getKeyWordsStr());
        }
        if (memberCardForm.getKeyWordsStr().matches("[a-zA-Z]*")) {
            memberCardForm.setName(memberCardForm.getKeyWordsStr());
        }
        List<MemberCard> list = this.lambdaQuery()
                .like(Objects.nonNull(memberCardForm.getName()), MemberCard::getName, memberCardForm.getName())
                .like(Objects.nonNull(memberCardForm.getMobile()), MemberCard::getMobile, memberCardForm.getMobile())
                .list();
        List<MemberCardPO> collect = list.stream().map(MemberCardPO::fromEntity).collect(Collectors.toList());
        return collect;

    }
}
